package com.alibaba.citrus.cr.unified.inventory.functions.handler;

import com.alibaba.citrus.cr.unified.inventory.contants.FeaturesKey;
import com.alibaba.citrus.cr.unified.inventory.model.enums.ReceiveStatus;
import com.alibaba.citrus.cr.unified.inventory.model.enums.ShipStatus;
import com.alibaba.citrus.cr.unified.inventory.utils.CompareUtil;
import com.alibaba.cz.base.tool.FeatureUtil;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSON;
import com.epoch.app.crunifiedinventory.domain.allocateorder.model.AllocateOrder;
import com.epoch.app.crunifiedinventory.domain.allocateorderdetail.model.AllocateOrderDetail;
import com.epoch.app.crunifiedinventory.model.enums.AllocateOrderStatus;
import org.apache.commons.collections4.MapUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @description: 公共的调拨单状态处理
 * @author: yuhw
 * @date: 2024年01月26日 10:56
 **/
public abstract class AbstractCommonAllocateOrderStatusHandler implements AllocateOrderStatusHandler{
    private static Log log = Log.getLogger(AbstractCommonAllocateOrderStatusHandler.class);

    @Resource
    private CommonAllocateOrderStatusCompute commonAllocateOrderStatusCompute;

    /**
     * 更新主单
     * @param allocateOrder
     */
    public void process(AllocateOrder allocateOrder, List<AllocateOrderDetail> detailList, boolean isFreightYardReceive){
        List<AllocateOrderStatus> statusList = detailList.stream().map(AllocateOrderDetail::getStatus).map(AllocateOrderStatus::of).collect(Collectors.toList());
        AllocateOrderStatus mainStatus = commonAllocateOrderStatusCompute.computeMainStatus(statusList);
        allocateOrder.setStatus(mainStatus.getValue());
    }

    /**
     * 更新子单
     * @param allocateOrderDetail
     */
    public void process(AllocateOrderDetail allocateOrderDetail,boolean isFreightYardReceive){
        log.info("CommonAllocateOrderStatusHandler_request:{}", JSON.toJSONString(allocateOrderDetail));
        String quantity = allocateOrderDetail.getQuantity();
        String bizFeatures = allocateOrderDetail.getBizFeatures();
        Map<String, String> bizFeaturesMap = FeatureUtil.fromString(bizFeatures);
        if (MapUtils.isEmpty(bizFeaturesMap)){
            return;
        }

        //特判一些状态不处理
        if (CompareUtil.anyOf(allocateOrderDetail.getStatus(),AllocateOrderStatus.Cancel.getValue())){
            log.info("CommonAllocateOrderStatusHandler_skip_status:{}",JSON.toJSONString(allocateOrderDetail));
            return;
        }
        //这里命名用ship?
        String deliveryQuantity = bizFeaturesMap.get(FeaturesKey.CUMULATIVE_DELIVERY_QUANTITY);
        String receiveQuantity = bizFeaturesMap.get(FeaturesKey.CUMULATIVE_RECEIVED_QUANTITY);

        if (Boolean.TRUE.equals(allocateOrderDetail.getClose())){
            if (CompareUtil.lessThanOrEqual(deliveryQuantity, BigDecimal.ZERO.toString()) &&
                    CompareUtil.lessThanOrEqual(receiveQuantity, BigDecimal.ZERO.toString())) {
                log.info("CommonAllocateOrderStatusHandler_skip_compute:{}",JSON.toJSONString(allocateOrderDetail));
                return;
            }
        }
        //数量比较
        //发货 未发, 部分发, 全发
        //收货 未收, 部分收, 全收
        ShipStatus shipStatus = computeShipStatus(deliveryQuantity, quantity,allocateOrderDetail.getClose());
        log.info("computeShipStatus:{}",JSON.toJSONString(shipStatus));
        ReceiveStatus receiveStatus = computeReceiveStatus(receiveQuantity, quantity,allocateOrderDetail.getClose());
        log.info("computeReceiveStatus:{}",JSON.toJSONString(receiveStatus));

        //收发状态合起来比较, TODO 这里的状态是否会有关闭/取消的影响
        AllocateOrderStatus allocateOrderStatus = commonAllocateOrderStatusCompute.computeStatus(shipStatus,receiveStatus);
        log.info("CommonAllocateOrderStatusHandler_result:{}", JSON.toJSONString(allocateOrderStatus));
        allocateOrderDetail.setStatus(allocateOrderStatus.getValue());
    }



    private ShipStatus computeShipStatus(String deliveryQuantity, String quantity,Boolean isClose){
        boolean greaterThan = CompareUtil.greaterThan(deliveryQuantity, BigDecimal.ZERO.toString());
        boolean lessThan = CompareUtil.lessThan(deliveryQuantity, quantity);
        if (greaterThan){
            if (Boolean.TRUE.equals(isClose)){
                return ShipStatus.ALL;
            }
            if (lessThan){
                return ShipStatus.PART;
            }else {
                return ShipStatus.ALL;
            }
        }
        return ShipStatus.NONE;
    }

    private ReceiveStatus computeReceiveStatus(String receiveQuantity, String quantity,Boolean isClose){
        boolean greaterThan = CompareUtil.greaterThan(receiveQuantity, BigDecimal.ZERO.toString());
        boolean lessThan = CompareUtil.lessThan(receiveQuantity, quantity);
        if (greaterThan){
            if (Boolean.TRUE.equals(isClose)){
                return ReceiveStatus.ALL;
            }
            if (lessThan){
                return ReceiveStatus.PART;
            }else {
                return ReceiveStatus.ALL;
            }
        }
        return ReceiveStatus.NONE;
    }

}
